/**  promise 需求清单
 *   1.属于一个类, 接收一个包含两个参数(可选)的函数 ，在实例化后直接运行
 *   2.拥有一个全局状态  ，  初始化时为  pending ，可以由 pendiing->fulfilled   ||  pending->rejected，一旦状态变更就不会在变
 *   3.实例对象拥有then方法 ，接收两个参数（可选），第一个为fulfilled回调，第二个为rejected回调
 *      （1）then方法可以链式调用
 *      （2）then方法回调返回的参数会传递给下个then方法
 *              then方法的回调返回不能为当前promise对象
 *      （3）返回一个新的promise
 *       (4) then方法可以重复调用
 *   4.catch方法
 *   5.finally
 *   6.all
 *   7.race
 *   8.allSettled
 *   9.any
 *   10.resolve
 *   11.reject
 *   12.try
 *
 */
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
  constructor(func) {
    try {
      func(this.resolve, this.reject);
    } catch (e) {
      this.reject(e);
    }
  }
  //状态
  state = PENDING;
  //成功的值
  fulfilledVal = undefined;
  //失败的值
  rejectedVal = undefined;
  //成功回调容器
  fulfilledBackContainer = [];
  //失败回调容器
  rejectedBackContainer = [];

  resolve = (val) => {
    if (this.state !== PENDING) return;
    this.state = FULFILLED;
    this.fulfilledVal = val;
    while (this.fulfilledBackContainer.length) {
      this.fulfilledBackContainer.shift()();
    }
  };

  reject = (err) => {
    if (this.state !== PENDING) return;
    this.state = REJECTED;
    this.rejectedVal = err;
    while (this.rejectedBackContainer.length) {
      this.rejectedBackContainer.shift()();
    }
  };

  then(fulfilledBack, rejectedBack) {
    fulfilledBack =
      typeof fulfilledBack === "function" ? fulfilledBack : (val) => val;
    rejectedBack =
      typeof rejectedBack === "function"
        ? rejectedBack
        : (err) => {
            throw err;
          };
    let promise = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        setTimeout(() => {
          try {
            let result = fulfilledBack(this.fulfilledVal);
            thenReturnDispance(promise, result, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      } else if (this.state === REJECTED) {
        setTimeout(() => {
          try {
            let result = rejectedBack(this.rejectedVal);
            thenReturnDispance(promise, result, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      } else {
        //异步情况
        this.fulfilledBackContainer.push(() => {
          setTimeout(() => {
            try {
              let result = fulfilledBack(this.fulfilledVal);
              thenReturnDispance(promise, result, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
        this.rejectedBackContainer.push(() => {
          setTimeout(() => {
            try {
              let result = rejectedBack(this.rejectedVal);
              thenReturnDispance(promise, result, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
      }
    });
    return promise;
  }

  catch(callBack) {
    return this.then(undefined, callBack);
  }

  finally
}
//then方法返回参数处理
function thenReturnDispance(promise, result, resolve, reject) {
  if (promise === result) {
    return reject(
      new TypeError("Chaining cycle detected for promise #<Promise>")
    );
  }

  if (result instanceof MyPromise) {
    //调用返回的promise的then方法获取到resolve或reject的值，在通过当前的promise的resole或reject 执行该值
    // result.then(val=>resolve(val),err=>reject(err))
    result.then(resolve, reject);
  } else {
    resolve(result);
  }
}

var demo = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject(6);
  }, 100);
});
demo
  .then(2)
  .then()
  .catch((res) => {
    console.log(res);
  });




